package cn.zhxu.toys.util;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 摘要工具类
 * @author 15735
 *
 */
public class DigestUtils {

	/**
	 * @return 长度 16  字节数组
	 */
    public static byte[] toMd5(byte[] source) {
        try {
        	return digest(source, "MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 MD5 算法：", e);
        }
    }
    
	/**
	 * @return 长度 32  的小写字符串
	 */
    public static String toMd5(String source) {
        return toMd5(source, StandardCharsets.UTF_8);
    }
	
	/**
	 * @return 长度 32  的小写字符串
	 */
    public static String toMd5(String source, Charset charset) {
        try {
        	return digest(source, "MD5", charset);
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 MD5 算法：", e);
        }
    }
    
    public static byte[] toSha1(byte[] source) {
        try {
        	return digest(source, "SHA-1");
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-1 算法：", e);
        }
    }
    
    public static String toSha1(String source) {
        return toSha1(source, StandardCharsets.UTF_8);
    }
    
    public static String toSha1(String source, Charset charset) {
        try {
        	return digest(source, "SHA-1", charset);
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-1 算法：", e);
        }
    }

    public static byte[] toSha224(byte[] source) {
        try {
        	return digest(source, "SHA-224");
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-224 算法：", e);
        }
    }
    
    public static String toSha224(String source) {
        return toSha224(source, StandardCharsets.UTF_8);
    }
    
    public static String toSha224(String source, Charset charset) {
        try {
        	return digest(source, "SHA-224", charset);
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-224 算法：", e);
        }
    }
    
    
    public static byte[] toSha256(byte[] source) {
        try {
        	return digest(source, "SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-224 算法：", e);
        }
    }
    
    public static String toSha256(String source) {
        return toSha256(source, StandardCharsets.UTF_8);
    }
    
    public static String toSha256(String source, Charset charset) {
        try {
        	return digest(source, "SHA-256", charset);
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-256 算法：", e);
        }
    }
    
    public static byte[] toSha512(byte[] source) {
        try {
        	return digest(source, "SHA-512");
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-512 算法：", e);
        }
    }
    
    public static String toSha512(String source) {
        return toSha512(source, StandardCharsets.UTF_8);
    }
    
    public static String toSha512(String source, Charset charset) {
        try {
        	return digest(source, "SHA-512", charset);
        } catch (NoSuchAlgorithmException e) {
            throw new DigestException("没有 SHA-512 算法：", e);
        }
    }
    
    public static String digest(String source, String algorithm) throws NoSuchAlgorithmException {
        return digest(source, algorithm, StandardCharsets.UTF_8);
    }
    
    public static String digest(String source, String algorithm, Charset charset) throws NoSuchAlgorithmException {
    	if (source == null) {
    		return null;
    	}
    	byte[] bytes = digest(source.getBytes(charset), algorithm);
        return StringUtils.toHexStr(bytes);
    }
    

    public static byte[] digest(byte[] source, String algorithm) throws NoSuchAlgorithmException {
    	if (source == null) {
    		return null;
    	}
    	MessageDigest md = MessageDigest.getInstance(algorithm);
        md.update(source);
        return md.digest();
    }
    
	public static class DigestException extends RuntimeException {

		/**
		 * 
		 */
		private static final long serialVersionUID = -1221087213990776777L;

		public DigestException(String arg0, Throwable arg1) {
			super(arg0, arg1);
		}
		
	}

}
